﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using TunnelsOfDeath.Objects;
using System.IO;
using System.Text.RegularExpressions;

namespace TunnelsOfDeath.LoadSave
{
    /// <summary>
    /// Class used only once after starting game. Du to the lack of the editor, maps can be created using spreadsheet software and saved as CSV files.
    /// These files can be then converted to XML map pack, that can be played ingame. CSV files are not needed anymore.
    /// </summary>
    class MapConverter
    {

        protected int Counter = 0;
        XDocument document = new XDocument();
        /// <summary>
        /// Start conversions.
        /// </summary>
        public void Convert()
        {
            if (!CheckForFile())
                return;

            XElement root = new XElement("Maps");
            document.Add(root);

            using (StreamReader sr = new StreamReader("map.csv"))
            {
                sr.ReadLine(); sr.ReadLine(); sr.ReadLine();

                while (!sr.EndOfStream)
                {
                    
                    string lineName = sr.ReadLine();
                    string name = Regex.Match(lineName, @"Name:\s(.*?),").Groups[1].Value;
                    XElement map = new XElement("Map");
                    map.SetAttributeValue("Name", name);
                    root.Add(map);


                    bool mapLoad = true;
                    string[] lines = null;

                    while (!sr.EndOfStream && mapLoad)
                    {
                        XElement column = new XElement("Column");

                        string line = sr.ReadLine();
                        lines = line.Split(',');
                        if (!string.IsNullOrWhiteSpace(lines[0]))
                        {

                            foreach (string item in lines)
                            {
                                if (!string.IsNullOrWhiteSpace(item))
                                {
                                    XElement field = ConverterStringtoMapField(item);
                                    column.Add(ConverterStringtoMapField(item));
                                }
                            }

                            map.Add(column);

                        }
                        else
                        {
                            mapLoad = false;
                        }
                    }

                }

                SaveXML("map.xml");


            }
        }

        protected bool CheckForFile()
        {
            return File.Exists("map.csv");
        }
        
        protected void SaveXML(string _filename)
        {
            document.Save(_filename);
        }

        protected XElement ConverterStringtoMapField(string _code)
        {
            XElement field = new XElement("Field");
            switch (_code.Substring(0, 1))
            {
                case "w":
                    field.Value = "wall";
                    break;
                case "d":
                    field.Value = "dirt";
                    break;
                case "p":
                    field.Value = "player";
                    AddPlayerAttr(_code, ref field);
                    break;
                case "n":
                    field.Value = "empty";
                    break;
                case "g":
                    field.Value = "gold";
                    break;
                case "r":
                    field.Value = "rock";
                    break;
                case "o":
                    field.Value = "door";
                    AddDoorAttr(_code, ref field);
                    break;
                case "e":
                    field.Value = "enemy";
                    AddEnemyAttr(_code, ref field);
                    break;
                default:
                    field.Value = "UNKNOWN!!!!!";
                    break;
            }
            



            return field;
        }

        private void AddPlayerAttr(string _code, ref XElement field)
        {
            if (_code.Substring(1, 1) == "1")
            {
                field.SetAttributeValue("Index", 1);
            }
            else
            {
                field.SetAttributeValue("Index", 2);
            }
        }

        private void AddDoorAttr(string _code, ref XElement field)
        {
            string strValue = Regex.Match(_code, @"o(\d)").Groups[1].Value;
            field.SetAttributeValue("Needed", strValue);
        }

        private void AddEnemyAttr(string _code, ref XElement field)
        {
            string strDirection = "";
            string strDelay = "";
            bool turnRight;

            if (_code.Length != 1)
            {
                Match match = Regex.Match(_code, @"e(\d)\.(\d*)?");
                strDirection = match.Groups[1].Value;
                strDelay = match.Groups[2].Value;
                turnRight = false;
                if (strDirection == "1")
                    turnRight = true;
            }
            else
            {
                strDelay = "1";
                turnRight = false;
            }

            field.SetAttributeValue("RightTurn", turnRight);
            field.SetAttributeValue("Delay", strDelay);


        }

    }
}
